package com.supreme.studyserver.config.handler;

import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.List;

public class MybatisSuperInterceptor implements InnerInterceptor {

    @Override
    public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        return true;
    }

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        String originSql = boundSql.getSql();
        System.out.println("sql = " + originSql);

        originSql = originSql.toLowerCase();
        int orderByIndex = originSql.lastIndexOf("order by");
        String beforeOriginSql = originSql.substring(0, orderByIndex).trim();
        String afterOriginSql = originSql.substring(orderByIndex).trim();

        StringBuilder sqlBuilder = new StringBuilder(beforeOriginSql);
        Class<?> parameterClazz = parameter.getClass();

        List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();
        /*String[] sqlArray = originSql.split("\\?");
        for (int i = 0; i < parameterMappingList.size(); i++) {
            ParameterMapping parameterMapping = parameterMappingList.get(i);
            System.out.println("parameterMapping = " + parameterMapping);
            String property = parameterMapping.getProperty();

            try {
                Field field = parameterClazz.getDeclaredField(property);
                field.setAccessible(true);
                Object parameterValue = field.get(parameter);

                sqlBuilder.append(sqlArray[i]).append(parameterValue);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }*/

        try {
            Field idField = parameterClazz.getDeclaredField("id");
            idField.setAccessible(true);
            idField.set(parameter, 357L);

            sqlBuilder.append(" and id = ?");
            Configuration configuration = ms.getConfiguration();
            ParameterMapping.Builder idBuilder = new ParameterMapping.Builder(configuration, "id", Long.class);
            parameterMappingList.add(idBuilder.build());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        sqlBuilder.append(" ").append(afterOriginSql);

        PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
        mpBoundSql.parameterMappings(parameterMappingList);
        mpBoundSql.sql(sqlBuilder.toString());
    }
}
